Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.ruby > #3614 > unrolled thread
| Started by | "amir e." <aef1370@gmail.com> |
|---|---|
| First post | 2011-04-28 04:48 -0500 |
| Last post | 2011-04-28 23:37 -0500 |
| Articles | 17 — 11 participants |
Back to article view | Back to comp.lang.ruby
Is everything object ? "amir e." <aef1370@gmail.com> - 2011-04-28 04:48 -0500
Re: Is everything object ? Urabe Shyouhei <shyouhei@ruby-lang.org> - 2011-04-28 04:56 -0500
Re: Is everything object ? Robert Klemme <shortcutter@googlemail.com> - 2011-04-28 04:59 -0500
Re: Is everything object ? Roger Braun <roger@rogerbraun.net> - 2011-04-28 04:54 -0500
Re: Is everything object ? Josh Cheek <josh.cheek@gmail.com> - 2011-04-28 06:52 -0500
Re: Is everything object ? Roger Braun <roger@rogerbraun.net> - 2011-04-28 10:26 -0500
Re: Is everything object ? Michael Sokol <mikaa123@gmail.com> - 2011-04-28 10:49 -0500
Re: Is everything object ? Josh Cheek <josh.cheek@gmail.com> - 2011-04-28 12:23 -0500
Re: Is everything object ? Josh Cheek <josh.cheek@gmail.com> - 2011-04-28 18:39 -0500
Re: Is everything object ? Josh Cheek <josh.cheek@gmail.com> - 2011-04-28 23:09 -0500
Re: Is everything object ? Josh Cheek <josh.cheek@gmail.com> - 2011-04-29 18:01 -0500
Re: Is everything object ? Brian Candler <b.candler@pobox.com> - 2011-04-28 15:22 -0500
Re: Is everything object ? Phillip Gawlowski <cmdjackryan@googlemail.com> - 2011-04-28 15:36 -0500
Re: Is everything object ? 7stud -- <bbxx789_05ss@yahoo.com> - 2011-04-28 11:54 -0500
Re: Is everything object ? 7stud -- <bbxx789_05ss@yahoo.com> - 2011-04-28 18:50 -0500
Re: Is everything object ? Stu <stu@rubyprogrammer.net> - 2011-04-28 14:43 -0500
Re: Is everything object ? Justin Collins <justincollins@ucla.edu> - 2011-04-28 23:37 -0500
| From | "amir e." <aef1370@gmail.com> |
|---|---|
| Date | 2011-04-28 04:48 -0500 |
| Subject | Is everything object ? |
| Message-ID | <62f261dc2ccebf22a5a04124a9b3bc7f@ruby-forum.com> |
Hi A very important principle in Ruby is that every thing is object. I read somewhere that there is no primitive operation in Ruby in traditional form and every operation is class. Now if every thing is object , then why + , - , * , ^ , ^^ isn't class Although they are primitive operation ? ps : If you test these codes , error happen : +.class -.class *.class -- Posted via http://www.ruby-forum.com/.
[toc] | [next] | [standalone]
| From | Urabe Shyouhei <shyouhei@ruby-lang.org> |
|---|---|
| Date | 2011-04-28 04:56 -0500 |
| Message-ID | <4DB939E8.4020401@ruby-lang.org> |
| In reply to | #3614 |
(04/28/2011 06:48 PM), amir e. wrote: > Hi > A very important principle in Ruby is that every thing is object. > I read somewhere that there is no primitive operation in Ruby in > traditional form and every operation is class. > Now if every thing is object , then why + , - , * , ^ , ^^ isn't > class Although they are primitive operation ? > > ps : If you test these codes , error happen : +.class -.class *.class > “Or else it doesn't, you know. The name of the song is called ‘Haddocks' Eyes.’” “Oh, that's the name of the song, is it?" Alice said, trying to feel interested. “No, you don't understand,” the Knight said, looking a little vexed. “That's what the name is called. The name really is ‘The Aged Aged Man.’” “Then I ought to have said ‘That's what the song is called’?” Alice corrected herself. “No, you oughtn't: that's quite another thing! The song is called ‘Ways And Means’: but that's only what it's called, you know!” “Well, what is the song, then?” said Alice, who was by this time completely bewildered. “I was coming to that,” the Knight said. “The song really is ‘A-sitting On A Gate’: and the tune's my own invention.”
[toc] | [prev] | [next] | [standalone]
| From | Robert Klemme <shortcutter@googlemail.com> |
|---|---|
| Date | 2011-04-28 04:59 -0500 |
| Message-ID | <BANLkTikf6CzpbaqUGPxgerRT=CdJWh8ZjQ@mail.gmail.com> |
| In reply to | #3614 |
On Thu, Apr 28, 2011 at 11:48 AM, amir e. <aef1370@gmail.com> wrote:
> A very important principle in Ruby is that every thing is object.
> I read somewhere that there is no primitive operation in Ruby in
> traditional form and every operation is class.
That wording does not really make sense. You probably mean that every
operator is a method, do you?
> Now if every thing is object , then why + , - , * , ^ , ^^ isn't
> class Although they are primitive operation ?
>
> ps : If you test these codes , error happen : +.class -.class *.class
I am not 100% sure what you are up to but in case you wonder whether
"+" is not something tangible (i.e. an object) this might explain:
operators (+, - etc.) are mainly syntactic sugar for method calls and
you can actually invoke them like methods:
irb(main):001:0> 1 + 2
=> 3
irb(main):002:0> 1.+(2)
=> 3
irb(main):003:0> 1.send("+", 2)
=> 3
irb(main):004:0> 1.send(:+, 2)
=> 3
irb(main):005:0> 1.method "+"
=> #<Method: Fixnum#+>
Kind regards
robert
--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/
[toc] | [prev] | [next] | [standalone]
| From | Roger Braun <roger@rogerbraun.net> |
|---|---|
| Date | 2011-04-28 04:54 -0500 |
| Message-ID | <BANLkTik6Qt_OBgPF1jBk4GGrZPYwdNNftQ@mail.gmail.com> |
| In reply to | #3614 |
Hi Amir, 2011/4/28 amir e. <aef1370@gmail.com>: > Hi > A very important principle in Ruby is that every thing is object. > I read somewhere that there is no primitive operation in Ruby in > traditional form and every operation is class. > Now if every thing is object , then why + , - , * , ^ , ^^ isn't > class Although they are primitive operation ? Methods always belong to a class in Ruby, but they are NOT objects (I hope this will change some day, maybe Ruby 2.0?). You can make method-like objects (procs or lambdas), though. -- Roger Braun rbraun.net | humoralpathologie.de
[toc] | [prev] | [next] | [standalone]
| From | Josh Cheek <josh.cheek@gmail.com> |
|---|---|
| Date | 2011-04-28 06:52 -0500 |
| Message-ID | <BANLkTimZhrtN8Y2c_auueOHsUwakAfgg=w@mail.gmail.com> |
| In reply to | #3614 |
[Note: parts of this message were removed to make it a legal post.] On Thu, Apr 28, 2011 at 4:48 AM, amir e. <aef1370@gmail.com> wrote: > Hi > A very important principle in Ruby is that every thing is object. > I read somewhere that there is no primitive operation in Ruby in > traditional form and every operation is class. > Now if every thing is object , then why + , - , * , ^ , ^^ isn't > class Although they are primitive operation ? > > ps : If you test these codes , error happen : +.class -.class *.class > > Those are methods, the Ruby interpreter uses syntactic sugar to make them look like operators. 1.methods.grep(/^[\W]/) # => [:-@, :+, :-, :*, :/, :%, :**, :==, :===, :<=>, :>, :>=, :<, :<=, :~, :&, :|, :^, :[], :<<, :>>, :+@, :=~, :!~, :!, :!=] (the leading colons means these are symbols, if you aren't familiar with symbols, you can think of them as a slightly different type of string) There are only three _relevant_ things that I can think of right now that aren't objects. Let us say that a thing is relevant as a nonobject if it means you can't manipulate it like an object (ie pass it as an argument, store it in a variable, and call methods on it). The first is boolean methods like "&&" and "||", the second is keywords like "class", and "def", the third is variables, which point to objects but are not objects themselves, thus cannot be pointed to by other variables. Using my above definition of "relevant", it is *not* relevant that methods and blocks aren't objects (in MRI), and I think it is better for your mental health and your understanding of the language if you forget that particular piece of pedantic trivia.
[toc] | [prev] | [next] | [standalone]
| From | Roger Braun <roger@rogerbraun.net> |
|---|---|
| Date | 2011-04-28 10:26 -0500 |
| Message-ID | <BANLkTi=gt0Tuh8e91NpbkXO8iT-FX+Fc3g@mail.gmail.com> |
| In reply to | #3618 |
2011/4/28 Chad Perrin <code@apotheon.net>: > For my purposes at least, it seems perfectly consistent that methods > should not be objects, in any case. Methods aren't *things*; they're > techniques *things* use to get stuff done. They are what objects know, > rather than being objects themselves. I can not completely agree with that. One reason why methods should be objects is because it is great to treat them like this (as the quasi-method-object called "block" proves) and makes a lot of stuff easier. Also, you can only bind objects to variables in Ruby, nothing else. So if I want to use a method in several places that don't know the method name beforehand, I have to wrap the method in a Proc object. BTW, having functions as objects is not really that unusual, see Javascript
[toc] | [prev] | [next] | [standalone]
| From | Michael Sokol <mikaa123@gmail.com> |
|---|---|
| Date | 2011-04-28 10:49 -0500 |
| Message-ID | <90AEE551-F0D9-478B-AAAF-5DD5DF249854@gmail.com> |
| In reply to | #3628 |
I think both of you are correct, in that: - Object are tangible things capable of processing -> composed of methods Thus an object isn't an entity that aggregate other entities (method objects). It's a closed, encapsulated, independent thing. However, it'd make sense to treat method as first-class objects. A method is only a procedure bound to an instance. In fact, Ruby allows you to do that: m = my_object.method( :a_method ) # returns a Method object bound to my_object m.call Michael Le 28 avr. 2011 à 11:26, Roger Braun <roger@rogerbraun.net> a écrit : > 2011/4/28 Chad Perrin <code@apotheon.net>: >> For my purposes at least, it seems perfectly consistent that methods >> should not be objects, in any case. Methods aren't *things*; they're >> techniques *things* use to get stuff done. They are what objects know, >> rather than being objects themselves. > > I can not completely agree with that. One reason why methods should be > objects is because it is great to treat them like this (as the > quasi-method-object called "block" proves) and makes a lot of stuff > easier. Also, you can only bind objects to variables in Ruby, nothing > else. So if I want to use a method in several places that don't know > the method name beforehand, I have to wrap the method in a Proc > object. > BTW, having functions as objects is not really that unusual, see Javascript. > > -- > Roger Braun > rbraun.net | humoralpathologie.de >
[toc] | [prev] | [next] | [standalone]
| From | Josh Cheek <josh.cheek@gmail.com> |
|---|---|
| Date | 2011-04-28 12:23 -0500 |
| Message-ID | <BANLkTikf8niyLZqcphfwQHiecfaGyTsLkw@mail.gmail.com> |
| In reply to | #3618 |
[Note: parts of this message were removed to make it a legal post.]
On Thu, Apr 28, 2011 at 10:12 AM, Chad Perrin <code@apotheon.net> wrote:
> I'm a little curious about why, to you, boolean methods are "relevant"
> and other methods are not. For that explanation, I would have just said
> that methods are not objects -- rather than saying something like
> "boolean methods aren't objects; let's not talk about other methods
> (which also aren't, but we shouldn't say that)".
>
>
Sorry, I wasn't very clear, it's a difficult subject to talk about because
the language is largely ambiguous.
Apparently, methods are *technically* not objects. Roger already brought it
up above, and it's been discussed before (
http://www.ruby-forum.com/topic/424911). Now, given that we can request a
method, and get an instance of Method, lets disregard this as it seems to me
to be an implementation detail.
So we can say that methods are objects, and everything suddenly makes sense
again. Operators are methods, and methods are objects, so operators are
objects. Except for boolean operators, which are not methods and thus not
objects. They are basically keywords. Here are some examples:
You can't define || or && on your object.
class Foo
def &(other)
"foo and #{other}"
end
end
Foo.new & 'bar' # => "foo and bar"
class Foo
def &&(other)
"foo and and #{other}"
end
end
Foo.new && 'bar' # ~> -:9: syntax error
You can't request them as methods, and thus can't pass them as arguments or
put them into block slots or store them in variables.
true.method '&' # => #<Method: TrueClass#&>
true.method '&&' # ~> -:1:in `method': undefined method `&&' for class
`TrueClass' (NameError)
With normal operators you can do fun stuff like this
plus_ten = 10.method('+')
[1,2,3,4,5].map(&plus_ten) # => [11, 12, 13, 14, 15]
But you can't do anything like that with &&, because it's not a method.
I was thinking about it just now, and realized assignment methods are the
same way. For example, you can't define +=
[toc] | [prev] | [next] | [standalone]
| From | Josh Cheek <josh.cheek@gmail.com> |
|---|---|
| Date | 2011-04-28 18:39 -0500 |
| Message-ID | <BANLkTikd7b=TRHuGmxyKQNuiw7irPVQHDQ@mail.gmail.com> |
| In reply to | #3638 |
[Note: parts of this message were removed to make it a legal post.]
On Thu, Apr 28, 2011 at 3:22 PM, Chad Perrin <code@apotheon.net> wrote:
> Oh, you're talking about boolean operators. I thought you were talking
> about actual boolean *methods*:
>
> irb(main):001:0> foo = Hash.new
> => {}
> irb(main):002:0> foo.empty?
> => true
>
>
I think of operators as methods. Probably the best term for those is
predicate.
> . . . but I dispute the argument you present that methods are objects.
> The fact that one can wrap a method in a "method object" does not make
> the method *itself* an object; it just creates an object that has a
> particular kind of interface to the method.
>
>
I'm not saying that methods are objects, I'm saying that calling them
non-objects serves no purpose, and choosing to think of them as objects (as
Ruby obviously wants you to) allows Ruby to be elegant again.
[toc] | [prev] | [next] | [standalone]
| From | Josh Cheek <josh.cheek@gmail.com> |
|---|---|
| Date | 2011-04-28 23:09 -0500 |
| Message-ID | <BANLkTinss5sdcrUq=VcUwgVKD2Cheo39Kw@mail.gmail.com> |
| In reply to | #3665 |
[Note: parts of this message were removed to make it a legal post.]
On Thu, Apr 28, 2011 at 10:40 PM, Chad Perrin <code@apotheon.net> wrote:
> On Fri, Apr 29, 2011 at 08:39:14AM +0900, Josh Cheek wrote:
> > On Thu, Apr 28, 2011 at 3:22 PM, Chad Perrin <code@apotheon.net> wrote:
> > >
> > > Oh, you're talking about boolean operators. I thought you were talking
> > > about actual boolean *methods*:
> > >
> > > irb(main):001:0> foo = Hash.new
> > > => {}
> > > irb(main):002:0> foo.empty?
> > > => true
> >
> > I think of operators as methods. Probably the best term for those is
> > predicate.
>
> Thinking of them as methods is probably a bad idea. It may lead you to
> make unwarranted assumptions about things you can do with them.
>
>
Can you be more explicit? They are methods, I don't understand what you
mean.
> > I'm not saying that methods are objects, I'm saying that calling them
> > non-objects serves no purpose, and choosing to think of them as objects
> (as
> > Ruby obviously wants you to) allows Ruby to be elegant again.
>
> It's perfectly "elegant" in terms of a consistent model without
> mislabeling methods as objects. Ruby does not seem to "want" me to think
> of methods as objects, else stuff like this would be meaningful
>
> puts.extend Enumerable
> puts.class
> foo(puts)
>
>
Those are meaningful, if you are interested in what the method returns
(nil). If you are interested in the method, then don't invoke it. Since
listing the method's name is syntactic sugar for invoking it, then how do
you get the method? Just ask for it method(:puts).extend(Enumerable)
On Thu, Apr 28, 2011 at 10:45 PM, Chad Perrin <code@apotheon.net> wrote:
> >
> > Do you have a real world example of that? Perhaps:
> >
> > (1, 2, 3).send(:ancestors)
>
> puts.extend Enumerable
>
>
That, of course works, puts evalutaes to nil, nil is an object and therefore
has a singleton class, and therefore can be extended.
puts # => nil
puts.singleton_class.ancestors # => [NilClass, Object, Kernel, BasicObject]
puts.extend Enumerable
puts.singleton_class.ancestors # => [NilClass, Enumerable, Object, Kernel,
BasicObject]
[toc] | [prev] | [next] | [standalone]
| From | Josh Cheek <josh.cheek@gmail.com> |
|---|---|
| Date | 2011-04-29 18:01 -0500 |
| Message-ID | <BANLkTinK-+dhyxsNbC7EmVYvrtq8PUHMyg@mail.gmail.com> |
| In reply to | #3676 |
[Note: parts of this message were removed to make it a legal post.] On Fri, Apr 29, 2011 at 2:37 PM, Chad Perrin <code@apotheon.net> wrote: > > > puts.extend Enumerable > > > > That, of course works, puts evalutaes to nil, nil is an object and > therefore > > has a singleton class, and therefore can be extended. > > It doesn't extend puts; puts is not an object. Trying to think of puts > as an object doesn't work. It gives surprising results if you actually > expect it to behave as an object in and of itself, thus violating the > "objects and methods" model of Ruby. > > > That's because methods are invoked by default, as I already stated. You need a line that evaluates to the method, not to nil. Your issue isn't with the objectivity of methods, it is with how you access methods. # this is evaluated puts # => nil # now we have a reference to it puts = method :puts # => #<Method: Object(Kernel)#puts> # and look, we can extend it puts.extend Enumerable # => #<Method: Object(Kernel)#puts> puts.singleton_class.ancestors # => [Enumerable, Method, Object, Kernel, BasicObject]
[toc] | [prev] | [next] | [standalone]
| From | Brian Candler <b.candler@pobox.com> |
|---|---|
| Date | 2011-04-28 15:22 -0500 |
| Message-ID | <2b40a6944b6aa778473e391ab4115eb9@ruby-forum.com> |
| In reply to | #3618 |
Josh Cheek wrote in post #995509: > There are only three _relevant_ things that I can think of right now > that > aren't objects. Let us say that a thing is relevant as a nonobject if it > means you can't manipulate it like an object (ie pass it as an argument, > store it in a variable, and call methods on it). The first is boolean > methods like "&&" and "||", the second is keywords like "class", and > "def", > the third is variables, which point to objects but are not objects > themselves, thus cannot be pointed to by other variables. I think it's reasonable to say that most operators in Ruby are in fact syntactic sugar for method calls; so are some other syntactic constructions like a[b] and a[b] = c. All these can be invoked equivalently using send, e.g. a.send(:[]=, b, c) However the assignment operators =, +=, -= etc are *not* mapped to method calls, in addition to the short-circuit boolean operators as you've already pointed out. It's perhaps also worth mentioning that literals don't invoke method calls; e.g. "foo" and /foo/ can't be intercepted by redefining String.new or Regexp.new -- Posted via http://www.ruby-forum.com/.
[toc] | [prev] | [next] | [standalone]
| From | Phillip Gawlowski <cmdjackryan@googlemail.com> |
|---|---|
| Date | 2011-04-28 15:36 -0500 |
| Message-ID | <BANLkTi=cVqewOYBUtg2TJT94MeRASAN9HQ@mail.gmail.com> |
| In reply to | #3653 |
On Thu, Apr 28, 2011 at 10:22 PM, Brian Candler <b.candler@pobox.com> wrote: > > However the assignment operators =, +=, -= etc are *not* mapped to > method calls, in addition to the short-circuit boolean operators as > you've already pointed out. But they are syntactic sugar for the syntactic sugar (except for "=", which is probably better seen as a keyword): a += b expands to a = a + b. -- Phillip Gawlowski Though the folk I have met, (Ah, how soon!) they forget When I've moved on to some other place, There may be one or two, When I've played and passed through, Who'll remember my song or my face.
[toc] | [prev] | [next] | [standalone]
| From | 7stud -- <bbxx789_05ss@yahoo.com> |
|---|---|
| Date | 2011-04-28 11:54 -0500 |
| Message-ID | <3c0cd959a902670e0183b8ff829f1d60@ruby-forum.com> |
| In reply to | #3614 |
amir e. wrote in post #995492: > Hi > A very important principle in Ruby is that every thing is object. > I have never found that claim to be important in any language. Whether everything is an object or just most things doesn't make a bit of difference in writing programs. Now if you were selected to be on a Ruby Trivia Show, and you can win thousands of $$$, then it would be helpful to know. -- Posted via http://www.ruby-forum.com/.
[toc] | [prev] | [next] | [standalone]
| From | 7stud -- <bbxx789_05ss@yahoo.com> |
|---|---|
| Date | 2011-04-28 18:50 -0500 |
| Message-ID | <7f2b6b723e1d9f0236f099f72f9cf228@ruby-forum.com> |
| In reply to | #3630 |
Chad Perrin wrote in post #995626: > On Fri, Apr 29, 2011 at 01:54:20AM +0900, 7stud -- wrote: >> amir e. wrote in post #995492: >> > >> > A very important principle in Ruby is that every thing is object. >> >> I have never found that claim to be important in any language. >> Whether everything is an object or just most things doesn't make a bit >> of difference in writing programs. Now if you were selected to be on a >> Ruby Trivia Show, and you can win thousands of $$$, then it would be >> helpful to know. > > It seems pretty unimportant until I try to interact with something as an > object and it turns out it *isn't* an object. Do you have a real world example of that? Perhaps: (1, 2, 3).send(:ancestors) -- Posted via http://www.ruby-forum.com/.
[toc] | [prev] | [next] | [standalone]
| From | Stu <stu@rubyprogrammer.net> |
|---|---|
| Date | 2011-04-28 14:43 -0500 |
| Message-ID | <BANLkTinu_QRzFY9UBHOFNyR57=sQNo6o9A@mail.gmail.com> |
| In reply to | #3614 |
Everything is a sender and receiver in ruby. The operators you list
are methods tied to the classes they work on. This is known as
polymorphism.
ex:
4 + 6
is
4.+( 6)
see Object dot method with argument (can be read 4.add(6) )
Ruby has a way where the interpreter will work without the dot and parenthesis
Where the polymorphic design of the language comes in is the
redefinition of + for other class types such as strings and
collections. for a string it will concatenate:
"Hello, " + " world!"
is
string.concat(string)
observe this in irb as well:
"Hello, ".+("world")
String.new("Hello, ").+("world")
These are all equivalent.
last example:
[42,17,3.14] + [999]
is
Array.new( [42,17,3.14]).+( [999])
So essentially the primitive operations as you word it are really
complex and cleverly designed methods provided to give the illusion of
they are primitive. They are methods in ruby. redefined in each
respective class to provide the proper abstraction on the type of data
the operands are dealing with.
If this may give you a better perspective on your question let's break
the interpreter. Type this in irb:
class Fixnum
def +(arg)
42
end
end
now running any addition will result with the number 42.
Of course you don't want to mess with the numerical classes but when
you go on to write your own classes it may come in handy to redefine
these operand methods within those classes to aid in the classes
abstraction.
~
On Thu, Apr 28, 2011 at 4:48 AM, amir e. <aef1370@gmail.com> wrote:
> Hi
> A very important principle in Ruby is that every thing is object.
> I read somewhere that there is no primitive operation in Ruby in
> traditional form and every operation is class.
> Now if every thing is object , then why + , - , * , ^ , ^^ isn't
> class Although they are primitive operation ?
>
> ps : If you test these codes , error happen : +.class -.class *.class
>
> --
> Posted via http://www.ruby-forum.com/.
>
>
[toc] | [prev] | [next] | [standalone]
| From | Justin Collins <justincollins@ucla.edu> |
|---|---|
| Date | 2011-04-28 23:37 -0500 |
| Message-ID | <4DBA4062.70101@ucla.edu> |
| In reply to | #3614 |
On 04/28/2011 02:48 AM, amir e. wrote: > Hi > A very important principle in Ruby is that every thing is object. > I read somewhere that there is no primitive operation in Ruby in > traditional form and every operation is class. > Now if every thing is object , then why + , - , * , ^ , ^^ isn't > class Although they are primitive operation ? > > ps : If you test these codes , error happen : +.class -.class *.class Actually, "everything is an object" is probably a mantra Rubyists should drop, because people will get confused when they find they can't call methods on every piece of Ruby code. I would say all values in Ruby are objects and all expressions return a value. But there are (admittedly few) things which are not expressions. The best thing is to not worry too much about absolutes and just enjoy exploring. -Justin
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.ruby
csiph-web