This seems to work when the method name doesn't end in =
.
class C
def x= value = nil, &block
end
end
c = C.new
c.x = 1 # => fine
c.x=(2) # => fine
c.method(:x=).call { 3 } # => fine
c.x= { 4 } # => syntax error
c.x= do
5
end # => syntax error
Does anyone have any idea why this is, or whether there is a similar syntax to the two that don't work?
sample usage:
logger.level=(:debug) do
# log at debug level inside this block
end
there are of course many alternatives, such as:
logger.with_level(:debug) do
# log at debug level inside this block
end
i am just interested if i was missing something syntax-wise or if anyone had any explanation for this behavior.
Methods ending with =
are called Assignment methods , and as such all rules of assignment applies.
Any assignment statement can be depicted as
LHS = RHS
where LHS
is Left Hand Side, RHS
is Right Hand Side.
The RHS
is evaluated to be a new value for LHS
, and if use attempt to specify block as RHS
using {...}
, it will get interpreted as definition of Hash literal and result in compilation error for being invalid hash. Similarly, do...end
block will result in other compilation errors.
Assignment methods should always have single parameter whose value can be assigned to an instance variable, or whose value can be used to derive new value for the instance variable.
If you wish you can use Proc
or lambda
as parameter, as they are Objects.
class C
def x= value
@x = (value.class == Proc ? value.call : value)
p @x
end
end
c = C.new
# fine
c.x = -> {10}
c.x = lambda {20}
c.x = Proc.new {30}
They can, but calling them the regular way would cause the block to be evaluated as hash thus giving you SyntaxError
. You can still call them using Object#public_send
/ Object#send
:
def foo=
puts 'bar'
yield
puts 'baz'
end
public_send(:foo=) { puts 'quiz' } # bar quiz baz
foo= { puts 'fail' } # SyntaxError
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.