Why call of custom method doesn't work?

I have a code:

module Foo
class Config
attr_reader :config

def initialize
  @config = {}  <-- standard hash
end

def <<(key, val)   <-- I want to implement "<<" sign as a method

name
n_hash = {key => val}
if (@config.merge!(n_hash))
return true
else
return false
end
end

end
end

Now I call it:

c = Foo::Config.new

c << “name”, “value” <- This doesn’t work. …syntax error, unexpected
‘,’, expecting ‘)’

c.<<(“name”, “value”) <- this works. But it’s ridiculous such a call in
Ruby.

Why
c << “name”, “value”
doesn’t work?

Syntactic sugar only goes so far before you have to start being
explicit.
Otherwise you might start stepping on parallel assignment, for example.
a,b = 1,2

On Fri, Apr 5, 2013 at 10:32 PM, Wins L. [email protected] wrote:

def <<(key, val)   <-- I want to implement "<<" sign as a method

name

That does not work. You can only pass in one value (see below).

For your use case better implement []= operator.

  n_hash = {key => val}
  if (@config.merge!(n_hash))
    return true
  else
    return false
  end

That’s quite a complicated way to convert a boolean (result of #merge!)
into a boolean. The whole if else end construction is superfluous. And
it
won’t work, too, because Hash#merge! always returns self.

irb(main):001:0> h={}
=> {}
irb(main):002:0> h.merge! 1=>2
=> {1=>2}
irb(main):003:0> h.merge! 1=>2
=> {1=>2}
irb(main):004:0> h.merge!({})
=> {1=>2}

c << “name”, “value” ← This doesn’t work. …syntax error, unexpected
‘,’, expecting ‘)’

c.<<(“name”, “value”) ← this works. But it’s ridiculous such a call in
Ruby.

Why
c << “name”, “value”
doesn’t work?

Because << is a binary operator: arg1 op arg2 - that’s the way code is
parsed, i.e. it’s defined in the syntax. With the parentheses you made
it
an explicit method call, which works.

Kind regards

robert

Hi,

I’ve often wanted what I’m about to describe.

Some history about me, so you know this isn’t a complete noob question:
I understand separation of concerns and encapsulation quite well (at
least, I think I do). I’ve been programming in object oriented languages
for most of my life (I’m 37, and I started SmallTalk when I was 17).
I’ve programmed in most languages: SmallTalk, Java, Ruby, forth, Python,
C/C++, BASIC, VisualBasic, ASM, LISP (common, scheme, racket),
JavaScript, Self, bit of Haskell, Erlang etc., etc.

Context here is object-oriented message sending:

class Person
attr_accessor :mood
def say_hi_to(someone)
puts “hiya”
end
end

class Nerd < Person

likes inside, dislikes outside

end

class Jock < Person

likes outside, dislikes inside

end

class Socialite < Person

doesn’t care in or outside, but only likes places where people are

interacting socially
end

class Place
attr_accessor :inside, :social, :bookish
def initialize(&block)
if block
yield
end
end
end

class Playground < Place
def intiialize(&block)
self.inside = false
self.social = true
self.bookish = false
super(&block)
end
end

def Library < Place
def initialize(&block)
self.inside = true
self.social = false
self.bookish = true
super(&block)
end
end

def Field < Place
def initialize(&block)
self.inside = false
self.social = false
self.bookish = false
super(&block)
end
end

field = Field.new {
julian = Nerd.new
dave = Jock.new
greginsky = Socialite.new
}

So what I’m interested in, when an object sends a message to another
object, why is there no context-sensitivity? In other words, (all
judgements aside as this is just a trivial example), I’d like the nerd
to be defined as a person who dislikes outside areas, therefore behaves
according to his mood when he’s outside perhaps.

Instantiating a Nerd inside a FIeld… or messaging him with the say_hi
type message should be able to bear some context on what that nerd’s
reply is. I’m not stipulating a tight coupling of context to object, I
like decoupled contexts, and I like interfaces, but just like the
mechanism of introspection, it’d be useful and nice to be able to garner
some information about the calling context, especially if (and this is
my real beef) the calling context WANTS TO GIVE THE INFORMATION. The
obvious solution is simply to change the interface so it contributes a
variable which passes across this information, but versioning interfaces
is a complete pain - I’d like to have a common object (called caller,
possibly) that I could query from within a method without the caller
having to pass through “self” every single time. Thus we could then
apply some duck typing in the callee side and get it to ask some
questions of its context before responding to messages.

Am I missing some obvious design considerations here?

I guess I’m talking more about language design than language usage, so
there might be a better place to discuss this. Comments?

Julian

Wow, phone glitch, sorry.

I was going to say: there is a caller. It tells you the entire stack
of
the current method.

In theory it may also be possible to query the ObjectSpace to see what
objects hold a reference to your nerd. However there’s no ruby-level
concept for “only one Place can hold a reference to a Person” so to
enforce
that rule you’d have to set up either a .location ‘property’ on person
(a
ref back to the Place they’re in) or an authoritative person:place map,
or
something like that. But I think that’s not what you’re asking for.

Sent from my phone, so excuse the typos.

Sent from my phone, so excuse the typos.

On Sun, Apr 7, 2013 at 4:47 AM, Julian L.
[email protected]wrote:

Haskell, Erlang etc., etc.

Context here is object-oriented message sending:

So what I’m interested in, when an object sends a message to another
object, why is there no context-sensitivity? In other words, (all
judgements aside as this is just a trivial example), I’d like the nerd to
be defined as a person who dislikes outside areas, therefore behaves
according to his mood when he’s outside perhaps.

Maybe your design is not appropriate for the type of application you
have
in mind: why not make Place a member of Person since a person can be in
one
place at a time only anyway?

Also: you put boolean properties inside Place and subclasses which are
set
in each sub class constructor. They are obviously intended to control
some
form of behavior. If you tie values of these properties to the class so
closely it is much, much more reasonable to encode that differing
behavior
into implementations of sub class methods.

See also state and strategy patterns.

Instantiating a Nerd inside a FIeld… or messaging him with the say_hi

through “self” every single time.
That is usually a bad idea. What you accomplish with this is non
explicit
passing of state around. That usually interferes with testability: if
you
pass in everything explicitly it is no problem to create a mock
environment
to test the class. If there is implicit passing this is much harder or
even impossible. Plus, the code is much harder to understand since
passing
of the implicit data is not part of the interface.

Also, logic of a class is much more difficult to understand if it does
not
only depend on the instance’s state but also on some kind of hidden
state
which is made accessible to method implementations.

Caveat: I often find it difficult to have this type of discussion on
synthetic examples because in a real world case there is so much more
context and information about the purpose which is missing here. So
please
take everything I write with a grain of salt.

Thus we could then apply some duck typing in the callee side and get it to
ask some questions of its context before responding to messages.

I am not sure I understand what you mean by “duck typing” here - I get
the
impression that you might not have fully understood the concept. With
duck
typing you would just invoke methods on the context and work from there.

Am I missing some obvious design considerations here?

I guess I’m talking more about language design than language usage, so
there might be a better place to discuss this. Comments?

I think this place is OK. In fact I am missing these types of
discussions
which seem to have become very rare. Thank you for bringing this up and
giving an opportunity to once again reason about design!

Kind regards

robert