13
\$\begingroup\$

The Task

I guess everybody loves automatic code generation and saving some time during work. You have to create a lot of classes and members during the day and you don't want to create all those getters manually.

The task is to write a program or function, that generates getters for all class members automatically for you.


The Input

In our language objects are very simple. Names of classes and members must start with an chararacter from [a-zA-Z] and can only contain the characters [a-zA-Z0-9]. Here's an example:

class Stack {
    public overflow;
    protected trace;
    private errorReport;
}

The Output

This is a valid output based on the given example:

class Stack {
    public overflow;
    protected trace;
    private errorReport;

    public function getOverflow() {
        return this->overflow;
    }

    public function getTrace() {
        return this->trace;
    }

    public function getErrorReport() {
        return this->errorReport;
    }
}

The Getter

The requirements for a getter method are:

  • The function name must start with get followed by the member name with an uppercase initial.
  • The function has no parameters.
  • To return a variable use return this->memberName;.
  • getters and setters (see The Bonuses) must be grouped and must come after all variable declarations.

Example:

private value1;
private value2;

public function getValue1() { return this->value; }
public function setValue1(value) { this->value = value; }

public function getValue2() { return this->value; }
public function setValue2(value) { this->value = value; }

The Requirements

  • Create a program or a function.
  • Input can come from STDIN, command line arguments, function arguments, a file etc.
  • Any output format is acceptable from a simple return-value to a file or writing to STDOUT.
  • In- and output don't need to be formatted with whitespaces, newlines, tabs etc. This is a valid input: class A{protected a;}.
  • You can assume that the input is valid and your program can handle unexpected input unexpected as well.

The Bonuses

You can get down to 10% of your original byte count by withdrawing 30% for each feature:

A: Your program can address newly added variables and adds missing getters only (public function getB() { return this->b; } in this case):

class A {
    public a;
    public b;

    public function getA() { return this->a; }
}

B: Your program also generates setters:

class A {
    public a;
    public getA() { return this->a; }
    public setA(a) { this->a = a; }
}

C: Your program can handle static members:

class A {
    public static c;
    public static function getC() { return this->c; }
}

This is code golf – so shortest answer in bytes wins. Standard loopholes are disallowed.

\$\endgroup\$
  • 3
    \$\begingroup\$ This is my first question - a not too hard one. Hope you like it. Thanks to Martin Büttner for helpful tips in the Sandbox. \$\endgroup\$ – insertusernamehere Nov 12 '15 at 15:07
  • \$\begingroup\$ Will there only be one class per input? \$\endgroup\$ – Conor O'Brien Nov 12 '15 at 15:10
  • 2
    \$\begingroup\$ When supporting both bonuses A and B should items that have getters, but no setters, have setters in the output? \$\endgroup\$ – FryAmTheEggman Nov 12 '15 at 19:48
  • 1
    \$\begingroup\$ @FryAmTheEggman That's a very good question. I would say that for bonus B you can assume that the input is complete, so if there's a getter there's also a setter. \$\endgroup\$ – insertusernamehere Nov 12 '15 at 20:35
  • 2
    \$\begingroup\$ In which language are you allowed to refer to this in a static accessor? \$\endgroup\$ – Neil Nov 12 '15 at 22:38
12
\$\begingroup\$

Perl, 161 - 90% = 16.1 bytes

$/=0;$_=<>;for$g(/\bp\S*( +static)? +(\S*);/g){++$i%2?$c="public$g function":/get\u$g/||s/}$/$c get\u$g(){return this->$g;}\n$c set\u$g(x){this->$g=x;}\n}/}print
\$\endgroup\$
  • 5
    \$\begingroup\$ You beat the Pyth answer o_o kudos! \$\endgroup\$ – Conor O'Brien Nov 12 '15 at 22:18
9
\$\begingroup\$

Pyth, 198 bytes - 90% = 19.8 bytes 187 - 90% = 18.7 bytes 183 bytes - 90% = 18.3 bytes

pJ<rs.z6_1sm?}+=b"get"K+rh=Zed1tZJks[Y=N|@d1kGbK"(){return "=H+"this->"Z";}"YNG"set"K"(x){"H"=x;}"):Js["(?:(?:"=Y"public""|private|protected)(?!"=G" function "")( static)?) (\w+)")4\}

Must...beat...Perl...

187-byte/18.7-byte version

J<rs.z6_1s_+\},sm?}+=b"get"K+rh=Zed1tZJks[Y=N|@d1kGbK"(){return "=H+"this->"Z";}"YNG"set"K"(x){"H"=x;}"):Js["(?:(?:"=Y"public""|private|protected)(?!"=G" function "")( static)?) (\w+)")4J

198-byte/19.8-byte version

J<rs.z6_1s_,sm?}K+rhed1tedJks["public"=N|@d1k=G" function ""get"K"(){return this->"ed";}public"NG"set"K"("ed"){this->"ed"="ed";}"):J"(?:(?:public|private|protected)(?! function )( static)?) (\w+)"4J

TODO: More golfing!

\$\endgroup\$
  • 3
    \$\begingroup\$ +1 for Must beat pearl... \$\endgroup\$ – Tschallacka Nov 13 '15 at 12:26
5
\$\begingroup\$

JavaScript ES6 (at the moment), 305 289 223 - 60% = 89.2 bytes

Was 256 - 30% = 179.2 bytes

Qualifies for static and setter bonuses; now with extra ES6!

s=>s.replace(/\}$/,s.match(/(public|private)( static)* \w+/g).map(e=>{o=(r=e.split` `).pop();return(n=r.join` `)+` get${U=o[0].toUpperCase()+o.slice(1)}(){return this->${o};}${n} set${U}(${o}){this->${o}=${o};}`}).join``+"}")

ES5 function, 115.6 bytes

function g(s){return s.replace(/\}$/,s.match(/(p(?:ublic|rivate))( static)* (\w+?);/gm).map(function(e){o=(r=e.split(" ")).pop().replace(/;/,"");return(n=r.join(" "))+" get"+(U=o[0].toUpperCase()+o.slice(1))+"(){return this->"+o+";}"+n+" set"+U+"("+o+"){this->"+o+"="+o+";}"}).join("")+"}")}
\$\endgroup\$
  • 1
    \$\begingroup\$ I think o.slice(1,o.length)) can simply be shortened to o.slice(1)), and I think you can inline v, since you only use it once (i.e., start your function with return s.replace(/\}$/, s.match(...).map...). Also, I don't believe you need a space between return and (. \$\endgroup\$ – apsillers Nov 12 '15 at 17:51
  • \$\begingroup\$ @apsillers Good point. I was going to do the second suggestion, but I simply had no time. Thanks for your golfs! ^_^ \$\endgroup\$ – Conor O'Brien Nov 12 '15 at 18:05
  • 2
    \$\begingroup\$ I think you can save 2 bytes just having public|private in your regex! \$\endgroup\$ – Dom Hastings Nov 12 '15 at 20:25
3
\$\begingroup\$

CJam, 71 bytes

q';/W<_{S%W=:O(eu"public function get"\@"{return this->"O";}"}%\';f+\'}

Try it online in the CJam interpreter.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.