Get The Getters

13

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.

insertusernamehere

Posted 2015-11-12T15:05:45.600

Reputation: 4 551

3

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.

– insertusernamehere – 2015-11-12T15:07:01.067

Will there only be one class per input? – Conor O'Brien – 2015-11-12T15:10:44.137

If the input has no newlines, should the output have any? – kirbyfan64sos – 2015-11-12T15:12:31.213

@CᴏɴᴏʀO'Bʀɪᴇɴ Yes, there will be only one class per input. – insertusernamehere – 2015-11-12T15:13:03.620

@kirbyfan64sos Newlines are optional. The output can be pretty or minified. – insertusernamehere – 2015-11-12T15:13:53.720

2When supporting both bonuses A and B should items that have getters, but no setters, have setters in the output? – FryAmTheEggman – 2015-11-12T19:48:33.507

1@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. – insertusernamehere – 2015-11-12T20:35:48.733

Do the setters always have to take a variable of that name? For instance, would it be valid to generate public function setOverflow(x){this->overflow=x;}? – kirbyfan64sos – 2015-11-12T21:12:50.590

@kirbyfan64sos Yes that would be valid, as it doesn't break functionality. – insertusernamehere – 2015-11-12T21:14:01.990

2In which language are you allowed to refer to this in a static accessor? – Neil – 2015-11-12T22:38:14.200

@Neil Good catch - I thought nobody would notice. I saw my mistake after I posted it and there was already one answer. So I didn't want to change the requirements afterwards. It's a very special language. ;) – insertusernamehere – 2015-11-12T22:43:43.833

Answers

12

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

faubi

Posted 2015-11-12T15:05:45.600

Reputation: 2 599

5You beat the Pyth answer o_o kudos! – Conor O'Brien – 2015-11-12T22:18:06.693

9

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!

kirbyfan64sos

Posted 2015-11-12T15:05:45.600

Reputation: 8 730

3+1 for Must beat pearl... – Tschallacka – 2015-11-13T12:26:28.913

5

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("")+"}")}

Conor O'Brien

Posted 2015-11-12T15:05:45.600

Reputation: 36 228

1I 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 (. – apsillers – 2015-11-12T17:51:06.973

@apsillers Good point. I was going to do the second suggestion, but I simply had no time. Thanks for your golfs! ^_^ – Conor O'Brien – 2015-11-12T18:05:26.570

2I think you can save 2 bytes just having public|private in your regex! – Dom Hastings – 2015-11-12T20:25:32.950

3

CJam, 71 bytes

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

Try it online in the CJam interpreter.

Dennis

Posted 2015-11-12T15:05:45.600

Reputation: 196 637