Calling a method foo() or an object foo.method_call_here - both

Hello.

Situation is this:

I have a method call foo.

Calling this method works.

It can accept zero, up to an unlimited amount of arguments.

Examples:

foo
foo ‘hi’
foo ‘hi’,‘there’

So far, so good.

Now, to make this a little bit more complicated,
the first call to foo in this example, will invoke
the default argument. Example:

def foo(i = ‘default value here’, *other_arguments)
puts i
end

Now the thing is, I want to change the default value
to that method.

My first idea was to use a constant.

DEFAULT_ARGUMENT = ‘default value here’

And then:

def foo(i = DEFAULT_ARGUMENT)
end

But I also want to change the default argument, and
ruby annoys me when I do so, because it is a constant.
(Sidenote - ruby should either enforce that a constant
is a constant, or it should not warn about it. The
current solution is a middle-way, which I don’t
think is good.)

So my idea was to use an array as constant, because
ruby does not warn you if the content of an array
constant is changed.

DEFAULT_ARGUMENT = [‘default value here’]

And then:

def foo(i = DEFAULT_ARGUMENT[0])

I then came up with a slightly better
solution. I will wrap this into a module, like
so:

module Foo
DEFAULT_ARGUMENT = [‘default value here’]
def self.to_s
return DEFAULT_ARGUMENT[0]
end
def self.set_new_default(i)
DEFAULT_ARGUMENT[0] = i
end
end

def foo(i = Foo.to_s)
end

This works nicely. If anyone has a cleaner or
better solution, I am all ears.

But one thing is missing still, because I want
to be able to “work on a method object” directly,
without much syntax sugar.

Specifically, I want to do this here:

foo # use the first, initial default here
foo.set_new_default ‘bla’ # change to a new, different default here
foo # now we will use the new default ‘bla’ here.

Is there ANY way to achieve the above? Especially
with the syntax that I want to showed there.

The real code has several foo-like methods, and
I would like to change the default values that
these methods have, in exactly that unified way,
via .set_new_default()

Obviously, for any “foo.” call to work, it would have
to return an object or module on which to actually call
set_new_default()

I am not sure that this is possible though. Is this even
possible in Ruby? And if it is not possible, why is this
not possible?

For any helpful pointers, I am thankful.

Hi,

to be honest, I don’t think this idea of using global methods as
independend function objects with state on their own makes sense. And
the more complicated your hacks get, the more I’m sure that you’re
trying to force a procedural technique on an OOP language.

First of all, if you’re programming object oriented, then all your
methods should belong to a specific class (other than Object). And if
that’s the case, dynamic values are simply stored in instance variables:

#--------------------------------------
class Hallo
attr_writer :hello_str

def initialize
@hello_str = ‘Hallo world!’
end

def hello str = nil
puts str || @hello_str
end
end

h = Hallo.new
h.hello ‘Hi’ # ‘Hi’
h.hello # ‘Hallo world!’
h.hello_str = ‘Hallo Welt!’
h.hello # ‘Hallo Welt!’
#--------------------------------------

However, your idea is possible. You could define your own Function
class that takes a proc and calls it using the predefined default
values. But then you’d basically have to write your own variant of
Ruby’s method calling logic. The information about the parameter types
(required, optional, other) of a proc is accessible via Proc#parameters.

The question is if this is worth the effort.

Hi,

Your example unfortunately requires the leading name
of the object. This is not what I want, because it
would require additional typing effort. And with the
additional typing effort, the advantage of using the
code is not really there anymore. :frowning:

For instance:

h.hello ‘Hi’ # ‘Hi’
hello #

^^^ This would be ok, if it could work.

h.hello ‘Hi’ # ‘Hi’
h.hello # ‘Hallo world!’

^^^ This would require a leading “h.” to query, and thus
would not be an advantage over the current solution I
have. (I already use this in my current code, I am really
wanting to get rid of this, if possible. It reads much
nicer if I could focus solely on the method names
alone.)

However, your idea is possible. You could define your
own Function class that takes a proc and calls it using
the predefined default values.
But then you’d basically have to write your own
variant of Ruby’s method calling logic. The
information about the parameter types (required,
optional, other) of a proc is accessible via
Proc#parameters.

The question is if this is worth the effort.

Hmm. Not sure I understand what you mean here. I somehow
have to use a proc… you probably mean, a proc inside
the method foo(). Ok. But would that not change the way
I call the method syntactically?

If I could use the above syntax, then it might be worth
the effort however.

I currently " solve this all like this:

class Foo # code inside it… about 6 lines of code.
end
def foo
end
Foo.set_default_value ‘bla’ # now all calls to foo() method have this
value

class Bar # code inside it… about 6 lines of code.
end
def bar
end
Boo.set_default_value ‘bla’ # now all calls to bar() method have this
value

This already works. What I don’t like is that I need to call it upcased,
as in Foo.bla() and Bar.bla(), would be so much nicer if I could just
use it downcased.

I’d really love to be able to use this downcased in any way.

You write that it may be possible, but is it really possible?

I was thinking that, if I would have something like:

foo.set_default_value

I’d need to call the method anyway, and that method could then
return a specific object, perhaps stored in a global variable
or something. In other parts of that project I have something like this
here already:

def foo
$foo ||= Foo.new
end

But how would it then know what to do, especially if the method
in question is unbound, like so in “free form”:

def foo(input)
puts input

return Foo.new here, unless it already exists

end

But somehow, the method would have to know if it would be called
like so:

foo()
foo

vs. so:

foo.call_a_method_here # but this would actually mean:
foo().call_a_method_here()

Unless I am mistaken, with this syntax:

foo.call_a_method_here

There is absolutely no way to call a foo() method, and call on an object
on it, IF we also want to retain the foo() method standalone, without
message check right?

In other words:

foo
foo.call_a_method

Can never work together or?

I am fine if foo would return anything else, I only need to tap into the
object in question if the syntax call would be something like:

foo.call_a_method here

Does this make any sense? :slight_smile:

First of all, if you’re programming object oriented, then
all your methods should belong to a specific class (other
than Object). And if that’s the case, dynamic values are
simply stored in instance variables:

But all methods belong to a class already in ruby.

The problem is that I would always require the leading name
when for most “standalone” free-form methods I can omit
it.

It would be awesome if I could have methods as first class
functions in ruby, without having to specify the full name
to it. So that both foo and foo.bla would call a method -
in the first case, a method bound to class Object, in the
second case, a method on class (or module) foo (or whatever
foo() would return).

Marc H. wrote in post #1080941:

Your example unfortunately requires the leading name
of the object. This is not what I want, because it
would require additional typing effort. And with the
additional typing effort, the advantage of using the
code is not really there anymore. :frowning:

Well, you cannot have all at once. If you don’t want to change the
source code of Ruby, you have to make compromises. Either the calling
syntax will change, or you’ll have to prepend the object name.

But like I already said, this whole idea is rather strange. What’s the
actual use case? Isn’t there a better solution that doesn’t involve
messing with core functionalities of the language? If you find yourself
using a lot of global methods, I think there’s generally something
wrong.

On Wed, Oct 24, 2012 at 3:20 PM, Marc H. [email protected]
wrote:

Your example unfortunately requires the leading name
of the object. This is not what I want, because it
would require additional typing effort.

But you cannot use “foo” to denote the object and invoke the method at
the same time. This is simply not possible.

How about defining a function class:

class Function
attr_accessor :default

def call(x = default, *rest)
printf “x=%p rest=%p\n”, x, rest
end
end

or even

f = Class.new do
attr_accessor :default

def call(x=default, *rest)
printf “x=%p rest=%p\n”, x, rest
end
end.new

f = Function.new

f.call
f.default = 123
f.call

Cheers

robert

Robert K. wrote in post #1080954:

Sorry, this line belongs here:
f = Function.new

I already suggested a Function class, but he doesn’t want to use a
different calling syntax.

On Wed, Oct 24, 2012 at 3:41 PM, Robert K.
[email protected] wrote:

class Function
attr_accessor :default

def call(x = default, *rest)
printf “x=%p rest=%p\n”, x, rest
end
end

Sorry, this line belongs here:
f = Function.new

f.call
f.default = 123
f.call

Kind regards

robert

Yes, if I have to use:

f.method_name()

Then there is no real advantage.

It would have to be via

method_name

Well, you cannot have all at once. If you don’t want to change
the source code of Ruby, you have to make compromises.

I am fine with this. I just want to verify that there is
no alternative to what I want.

Either the calling syntax will change, or you’ll have to
prepend the object name.

I understand that now. Looks as if I can not get this
feature then. :frowning:

But like I already said, this whole idea is rather strange.
What’s the actual use case?

I have a few methods in a project that can only be
called via:

name

as in:

name_of_method_here
foo
bar

They all accept the “same” arguments though. Not the
same arguments of course, actually, but the name of
the arguments is all the same for each of those small
methods. For example:

def foo(css_class = nil, css_style = nil, object_id = nil)

end

By default, none of these arguments is mandatory. (There
are also lots more arguments to these methods, and block
usage via yield too, and in some cases *args, but I
simplified it to keep it simpler for here, just to
demonstrate)

What I want to have is the ability to easily change
all these methods’ arguments BUT only if I specifically
want to do so, by accessing the name of the method in
question.

The current solution I have is:

Foo.css_class = ‘bla’ # or the alternative, via set_css_class, does not
really matter

The only thing I am unhappy with it so far is the upcased name
but I guess it can not get better than that.

For instance, the perfect syntax would then actually
be this here:

foo.css_class = ‘red’

^^^ That would be perfect if that could work! But of
course you can not change default parameters in methods
so easily. :frowning:

I’d love to be able to access them like data structures
on objects. Or on Ruby structs.

Isn’t there a better solution that doesn’t involve
messing with core functionalities of the language?

If you have an idea with shorter syntax, sure. But
all proposals so far required longer syntax. I don’t
really seek something that is longer than what I want
because I know how to solve that already (or perhaps
you know of a more elegant way, I have not explored
everything - perhaps there is a solution with procs,
but they are kind of mysterious to me, and if I
have to prepend via “x.” then this is not elegant).

If you find yourself using a lot of global methods,
I think there’s generally something wrong.

That is unspecific. I mean, what exactly is wrong here.

I don’t know what to do with such a general statement. :slight_smile:

Do you have a specific suggestion for a shorter
solution?

The methods are not really “global”, they all reside
in a module, and that module is pulled in when the
project is required.

There is no way I will change this project to require
the leading “foo.” ever, because that would inflate
the whole code of my project by +100% for no net gain
at all. It can be argued a lot that the proper way
would be to use:

Foo.call_method_here

But:

call_method_here

Simply is shorter.

I love succintness and terseness.

On Wed, Oct 24, 2012 at 8:01 PM, Marc H. [email protected]
wrote:

Yes, if I have to use:

f.method_name()

Then there is no real advantage.

But you can at least have

f[]
f[1, ‘foo’, 77]

as I have shown in my example.

robert

Marc H. wrote in post #1080984:

If you find yourself using a lot of global methods,
I think there’s generally something wrong.

That is unspecific. I mean, what exactly is wrong here.

I think you might be using the wrong language. If you want to program
with functions and view the “object.” part as nothing but an annoying
prefix to the function names, I don’t really see the point of using an
object oriented language.

That’s like buying jazz music and saying that you don’t like the sound
of trumpets.

You insist on extremely short names, which makes absolutely no sense to
me. How often are you calling those methods in your code? 1000 times?
I’ve never heard this argument, because usually the length of code is
not determined by the length of names but by the general
structure (which sounds rather repitituous in your case, because you
said you have different methods with the same very long parameter list).

This all sounds very strange to me. You still haven’t said what you’re
trying to do. Your methods sound like you’re generating HTML elements?
Then maybe a template engine is what you’re looking for?

I think you might be using the wrong language.

Now you advocate to use another language?

Which one precisely?

I also fail to see how your suggestion of using another language has
anything to do with the problem description.

If you want to program with functions

There are no “functions” in Ruby.

Even foo() is a private method on class Object.

view the “object.” part as nothing but an annoying
prefix to the function names

Yes, I did explain to you why that is so.

It is more code to type. See DSLs implemented - you
will not see them prefix ANYTHING at all. That would ruin
the whole purpose of them.

I don’t really see the point of using
an object oriented language.

That is nice that you have this opinion.

However I am not sure why you need to give your opinion
here in regards to the problem description.

You even recommend to use another language. :slight_smile:

That’s like buying jazz music and saying that you
don’t like the sound of trumpets.

I buy a car and I want to tinker with it.

If you are happy with the car you bought, that is nice,
but don’t come to me and tell me that I should stop
tinkering with MY car.

You insist on extremely short names, which makes
absolutely no sense to me.

I do not need to convince you. Why do you put yourself
into the center of what I want? Does it matter to
you on a personal level? And if you are unwilling
or unable to help, which is fine, why do you
comment?

How often are you calling those methods in your
code?

I use it for a template language. I use it a lot.

1000 times? I’ve never heard this argument, because
usually the length of code is not determined by
the length of names but by the general structure

Yes, it is. If I use 100000 instances of this, then
I want it to be as succint and as easy to use as
possible.

If you fail to see the point or advantage in being
succint, that is your problem.

(which sounds rather repitituous in your case,
because you said you have different methods with
the same very long parameter list).

Correct. However, the methods do have differences
in their implementation. Some of them require more
code than others.

This all sounds very strange to me.

That is good to know. However, how does this help?

You still haven’t said what you’re trying to do.

I did so before already. You replied that "you do not
see the point. You also suggested that I should
use another language.

Is this what the mailing list here is about? That
people suggest to use another language?

Your methods sound like you’re generating HTML elements?

In some ways, yes. But you try to limit the framework
and goal of the whole project. Accept that this is
ONE component of what I would like to do.

Then maybe a template engine is what you’re looking for?

Which one exactly?

And more importantly, which one would offer the ADVANTAGE
of being succint and terse?

I already know how to be verbose and long.

Marc H. wrote in post #1082039:

However I am not sure why you need to give your opinion
here in regards to the problem description.

This is not my opionion in the sense of “I like red more than blue”.
This is how I view the problem and what I would consider to solve it.
Unless you ask for e. g. the result of 1 + 1, there’s no definite
solution. Everything we suggest is based on our personal experiences and
estimations. And that’s exactly why I say “I think …”. It’s called
honesty. :wink:

Considering a different language was a serious suggestion. Some people
simply don’t adopt OOP and will always think procedurally. In this case
it might make sense to actually use a procedural language which
doesn’t come with all the OOP baggage. I’m not telling you to dump Ruby,
I’m simply saying: If you rarely use the OOP features and mostly try to
get rid of them, maybe it’s just not the right language.

Anyway, the more I think about this, the more I’m sure that a template
engine is what you want. What about Haml? http://haml.info/ This also
has the big advantage of not being embedded into the Ruby code, so the
templates are cleanly separated from the programming logic and easier to
edit.

A more “hackish” solution could be to change the execution context of
your Ruby methods so that they’re evaluated with the prefixed class
being “self” and don’t need an explicit receiver (see
instance_eval/class_eval/module_eval). Or you simply wrap the method
calls in another method of the module. Then you don’t even have to
fumble with “self”.

Marc H. wrote in post #1080918:

Specifically, I want to do this here:

foo # use the first, initial default here
foo.set_new_default ‘bla’ # change to a new, different default here
foo # now we will use the new default ‘bla’ here.

Hi,

I think it will be simpler if you could change

foo.set_new_default 'bla'

into

set_new_default(:foo, 'bla')   # or any variation of this

(You could then use a constant or a global variable to store the default
values.) But can you change it like this?

Regards,

Bill