I'd rather use a constant, but it looks like that doesn't work either:
./griva/della/ferrante/Start.mirah:13: undefined method
`transform_const_assign' for #<Mirah::AST::TransformHelper:0x11e3c2c6>
USER_AGENT = "Ferrante"
Any hints?
-Phil
OK, good to know. How much work would it be to wire them in? I'm not
above some compiler spelunking myself if I can get a few pointers.
-Phil
Are you specifically talking about class variables? I don't mind
losing them, but if so they should be disabled at compile time rather
than just always returning nil at runtime.
Or do you mean something about constant creation should be more like
Java? I don't actually know Java, so could you elaborate?
-Phil
Class variables do work, but they don't appear to work properly in the
class body. For example, this works:
➔ mirah -e "class Foo; def self.set; @@bar = 1; end; def self.print;
puts @@bar; end; end; Foo.print; Foo.set; Foo.print"
0
1
But @@bar = 1 in the class body seems to fail, claiming it's trying to
access the private "bar" field from the "DashE" class. Probably an
issue with not setting the "current" type when entering a class body
properly.
Phil: You could probably start poking around starting with
lib/mirah/transform2.rb at line 417 (def transform_class_var) to see
if you can sort out what's not working. There's also
transform_constant at 336, which may be more what you want...
- Charlie
So, syntax-wise, these would be equivalent?
class Foo
@bar = 1
end
And
class Foo
def initialize
@bar = 1
end
end
The only issue I have is that it might be confusing to people coming from Ruby, because in Ruby these are not equivalent, and we'd need to document that effectively.
As ribrdb suggested, class variable assignments in the class body should be moved into the static initializer.
So, syntax-wise, these would be equivalent?
class Foo
@bar = 1
endAnd
class Foo
def initialize
@bar = 1
end
endThe only issue I have is that it might be confusing to people coming from Ruby, because in Ruby these are not equivalent, and we'd need to document that effectively.
Right. I believe this is how it works in java. But you're right that it may be confusing for ruby users. I guess we need to decide what code in the body of the class should mean. I can see a few options:* Just allow initialization of fields. Instance variables are set in the constructor, class variables in the static initialzer. Other code in the class body is an error. This is most like java.
* Run it at compile time in the compiler for meta-programming. This would probably be most ruby like, but would probably be difficult to understand.
* Run it in the static initializer
* Run it in the constructors
Getting constants working is probably the most important task (just initializing them at the beginning of the static initializer). Other fields can probably wait since you can already manually initialize them in the constructors or static initializer.
On Tue, Dec 28, 2010 at 1:06 PM, Rib Rdb <rib...@gmail.com> wrote:Right. I believe this is how it works in java. But you're right that it may be confusing for ruby users. I guess we need to decide what code in the body of the class should mean. I can see a few options:* Just allow initialization of fields. Instance variables are set in the constructor, class variables in the static initialzer. Other code in the class body is an error. This is most like java.So, only simple things like:class Foo@bar = 1@@baz = 2endwould work? In this case, it would be nice to have static initializersyntax for cases where your class variables require some setup, maybesomething like,
class Foo@bar = 1static dorand = java.util.Random.new@@baz = rand.nextIntendend* Run it at compile time in the compiler for meta-programming. This would probably be most ruby like, but would probably be difficult to understand.running it at compile time would allow metaprogramming likeclass Foo < Model%w(bar baz).each do |name|param name, textendend
but things likeclass Barrand = java.util.Random.new@@baz = rand.nextIntendmight act weird--it's harder to understand and implement.
I think @@ should work everywhere to mean "class variable" or "static
variable". Code in the class body should probably only be implicitly
inserted in the class initialize (like the entire class body is an
implicit static { } block from Java). @var should not be allowed in
class body; it's perhaps the most confusing aspect of Ruby that @var
in a class body is an instance variable of the class, and @@var in a
class body is something different...a "class variable declaration".
So to summarize based on examples given:
> class Foo < Model
> def self.initialize
> @@bar = Random.new.nextInt
> end
> end
Valid. Explicit static initializer.
> class Foo < Model
> @@bar = Random.new.nextInt
> end
Valid. Implicit static initializer.
> class Foo < Model
> @@generator = Random.new
> @@bar = @@generator.nextInt
> end
Valid. Implicit static initializer.
> class Foo < Model
> @@a = 1 <-- static, right?
> @b = String(nil) <-- whats this?
> end
Invalid. @b has no meaning in a class body. @ vars are only instance
variables, and there's no containing instance.
class Foo
@@baz = generateRand
def self.generateRand
Random.new.nextInt
end
end
Valid. Static methods are available to be called from static
initializers, and @@baz = generateRand is in the implicit static
initializer.
Does that all sound reasonable? I think it's best to just make @ mean
instance and @@ mean static always, everywhere.
- Charlie
This bit is not clear to me:Why write:class Foo < Modeldef self.initialize@@bar = Random.new.nextIntendendWhy not just have this?class Foo < Model@@bar = Random.new.nextIntend
If I wanted to writeclass Foo < Model@@generator = Random.new@@bar = @@generator.nextIntendThen those command would just execute in the order that I wrote them, wouldn't they?
Second thing I don't understand - what does that single @ variable mean?class Foo < Model@@a = 1 <-- static, right?@b = String(nil) <-- whats this?endCould you please explain these to me? Maybe I don't know enough Java to understand :)
Yes, they should simply be a compile error.
> I think it would be nice to support instance variable initializers like java
> has, but I'd be fine to leave this out if it is too confusing. See the
> example in my last email -- assignments to an instance variable in the class
> body get copied into all constructors. (or perhaps collected into a private
> final method that's called from all constructors).
You make a good point. Hmm. I'm having trouble reconciling the fact
that the class body is both an implicit static initializer (a method,
where you can basically run any code) AND having instance variable
initializers moved from there into construction...
For consistency, it seems like we'd need to only allow variable
initialization in the class body. What would something like this do,
for example:
class Foo
@@a = true
if @@a
@a = false
end
end
It would be a pain to find any cases where an instance var isn't used
at the root of the class and turn them into errors...
- Charlie
On Tue, Dec 28, 2010 at 4:54 PM, Rib Rdb <rib...@gmail.com> wrote:Yes, they should simply be a compile error.
> I agree that @ should always mean instance and @@ should always mean static.
> (We should probably fix that @ in static methods means a static field now
> that @@ is working).
You make a good point. Hmm. I'm having trouble reconciling the fact
> I think it would be nice to support instance variable initializers like java
> has, but I'd be fine to leave this out if it is too confusing. See the
> example in my last email -- assignments to an instance variable in the class
> body get copied into all constructors. (or perhaps collected into a private
> final method that's called from all constructors).
that the class body is both an implicit static initializer (a method,
where you can basically run any code) AND having instance variable
initializers moved from there into construction...
For consistency, it seems like we'd need to only allow variable
initialization in the class body. What would something like this do,
for example:
class Foo
@@a = true
if @@a
@a = false
end
end
It would be a pain to find any cases where an instance var isn't used
at the root of the class and turn them into errors...
- Charlie
Maybe we can have it just be a syntax error; "instance variable
assignment must be rooted in class body" or something.
- Charlie
class Foo@@a = true
b)@b = true if @@a^^^^^^^^endError: if statement not valid in class body
class Foo@@a = true
@b = true if @@a^^^^^^^^^^endError: instance variable initialization must be rooted in class body
For what it's worth I agree; it seems like allowing this may not be
worth all the baggage and edge cases that come with it. Everyone knows
how initialize works; it's better to build on well-known and
well-understood constructs than to create new constructs with murky
semantics.
-Phil