I would prefer not to add another parameter to the method signiture to
signify this option b/c its rare and it would complexify the call to
much, especially if there is more than one optional part --which is
possible. But other tahn that I don’t have much choice, I’ll probably
have to create an extra method called #parse_multicommand_without_multi_flag. Yuk!
Not that helps me presently, but this did get me to thinking of using a
“global” flag that can be set external to the method. That would work
but it wouldn’t be thread safe. Then it occured to me the
Binding.of_caller could be helpful here. Using the Binding#[] extension
for local variable access:
I know this breaks the whole idea of function encapsulation, but it has
it’s advantages in certain cases like mine. It also might be of usedin
a few other places like String#each’s separator. So that got me to
thinking of a cleaner way to provided this capability of invasive
parameters as “method mode variables”.
My thoughts on your current suggestion: Yuck. You really want this
to become so common that the language itself supports it? I
definitely don’t. The whole usage case is a code smell, in my opinion.
My thoughts on your suggestions in general: You sure spend a lot of
time trying to rewrite Ruby’s syntax.
I would prefer not to add another parameter to the method signiture to
for local variable access:
no_multi_flag = true
argv = multi_flag(argv) unless --no_multi_flag
…
end
‘–’ indicates a method mode variable
–no_multi_mode = true
parse_multicommand( line )
Thouhgts?
method + state => object
harp:~ > cat a.rb
require 'rubygems'
require 'attributes'
class Parser
attribute 'no_multi_flag'
def parse_multicommand
p [:parse_multicommand, no_multi_flag]
end
def parsing &b
instance_eval &b
end
end
parser = Parser.new
parser.parsing{
no_multi_flag true
parse_multicommand
}
harp:~ > ruby a.rb
[:parse_multicommand, true]
good point. though it moves me away from the simplicity of single call.
also i wonder about things like String#each. the global default for
separator is not really the ideal implementation, but #each can’t be
made a class.
My thoughts on your current suggestion: Yuck. You really want this
to become so common that the language itself supports it? I
definitely don’t. The whole usage case is a code smell, in my opinion.
perhaps. just exploring the idea. certainly Binding.of_caller allows
this kind of thing more or less. and I think there are good occassions
to use Binding.of_caller. in this case the no_multi_key option would
rarely be used. so having to turn the whole thing into a class, as ara
suggests, for one (or two) uncommon parameter seems like overkill,
although maybe it is better to do so.
I did think of one other way it could be done, inspried by an idea _why
had long ago:
def no_multi_flag
class << self
def multi_flag(argv); argv; end
end
yield
class << self
undef_method :multi_flag
end
end
though that sort of smells worse in my opinion.
My thoughts on your suggestions in general: You sure spend a lot of
time trying to rewrite Ruby’s syntax.
I know. It’s sort or a hobby of mine. I have a general interest in
understanding the human <-> programming language interface.
I would have put it differently: command pattern. Your method seems
pretty complex so you can change it into a command object. If the
problem at hand is complex then it probably needs a complex solution.
But I would not go down the metaprogramming route.
good point. though it moves me away from the simplicity of single call.
also i wonder about things like String#each. the global default for
separator is not really the ideal implementation, but #each can’t be
made a class.
good point. though it moves me away from the simplicity of single call.
also i wonder about things like String#each. the global default for
separator is not really the ideal implementation, but #each can’t be
made a class.
And if we can do it gloablly, which is not ideal, then why not do it
better with a local “method mode variable”?
Because you commit a gross violation of encapsulation for zero
increase in expressiveness? =)
The violation is much worse with a global var. With a local var the
violation is very minimal, plus the varaible can be specifically
designated as “method mode”. So it’s actually very similar to keyword
arguments. Eg.
each(:separator => //)
Just with a little extra flexability in that the method mode can apply
to multiple calls in the same local scope and the mode variable doesn’t
have to intermingle with true data parameters.
As for expressiveness. I’m not sure how youre measuring that, the
to_enum version is clearly more convoluted (with exception of the $/
var, but that could be called $input_separator or some such name
instead too).
In anycase, perhaps any breakage of the local encapsulation is too
much, and matz will never grant us Binding.of_caller. But then why does
this global default on String#each persist?
hmm, interesting. ’ seems my mind likes that style. sometimes i’d wish #each can receive a param, so i don’t have to remember all those each_*
and #to_enum thingies. That would mean i could do something like the ff
The violation is much worse with a global var. With a local var the
violation is very minimal, plus the varaible can be specifically
designated as “method mode”.
You are exactly right: it is less of a violation. However, I think
this is the part where I’m supposed to mention something about a
``slippery slope.‘’
So it’s actually very similar to keyword arguments. Eg.
each(:separator => //)
Just with a little extra flexability in that the method mode can apply
to multiple calls in the same local scope and the mode variable doesn’t
have to intermingle with true data parameters.
Again, you are right, but why do this when you already have an
objects, whose entire reason for existence is to track state
information. Why not make it an honest to goodness part of the
interface?
enumerable.separator = //
use each
As for expressiveness. I’m not sure how youre measuring that, the
to_enum version is clearly more convoluted (with exception of the $/
var, but that could be called $input_separator or some such name
instead too).
No, it’s perfectly clear. What it lacks is concision, and while
concision is a desirable quality, it is not worth trading for clarity
and transparency. Saving a few keystrokes is not a good reason for
adding a new mechanism that acts at a distance.
In anycase, perhaps any breakage of the local encapsulation is too
much, and matz will never grant us Binding.of_caller. But then why does
this global default on String#each persist?
I can’t offer much insight on that, but I’d suspect it’s historical.
You are exactly right: it is less of a violation. However, I think
this is the part where I’m supposed to mention something about a
``slippery slope.’’
point taken.
No, it’s perfectly clear. What it lacks is concision, and while
concision is a desirable quality, it is not worth trading for clarity
and transparency. Saving a few keystrokes is not a good reason for
adding a new mechanism that acts at a distance.
Well, “perfectly” is certainly overstating but I take you point.
However, it’s not just keystrokes. Have to create a new Enumerator
object is also much less efficient.
In anycase, perhaps any breakage of the local encapsulation is too
much, and matz will never grant us Binding.of_caller. But then why does
this global default on String#each persist?
I can’t offer much insight on that, but I’d suspect it’s historical.
I had talked to matz about it once, and he essentially said he didn’t
want it for simplicity sake. I can;t say I quite understand that, but
there it is. hoever you just helped me release taht in 1.9+ the
situation is at least improved b/c
“string”.each(//) #=> enumerator
Still less efficent but at least concise. And the global default can go
away.
Well, “perfectly” is certainly overstating but I take you point.
However, it’s not just keystrokes. Have to create a new Enumerator
object is also much less efficient.
Busted. You’ll have to forgive me that small rhetorical flourish =)
What I meant to say is that the semantics of Enumerator aren’t very
hard to understand. Indeed it does induce some overhead, but I don’t
think it is in any way “convoluted”.
quite. it seems matz doesn’t care for symobolic paramters of this kind.
once i even asked him about a special case modification in arg
interpretation and precedence so we could do things like:
matz didn’t like. i think i can understand, there are pros and cons.
the important con is it would make subclassing and overriding a method
more difficult.
(OT) he also said he had a different idea for using ‘:’ in a method
name. other then :after and :back i wonder what it is and if it has
some general application?
t.
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.